package com.example.manager.service.impl;



import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.exception.GuiguException;
import com.example.common.helper.JwtHelper;
import com.example.common.utils.AuthContextUtil;
import com.example.manager.mapper.SysMenuMapper;
import com.example.manager.mapper.SysRoleMenuMapper;
import com.example.manager.mapper.SysUserRoleMapper;
import com.example.manager.service.SysMenuService;
import com.example.manager.utils.MenuHelper;
import com.example.model.entity.system.SysMenu;
import com.example.model.entity.system.SysRoleMenu;
import com.example.model.entity.system.SysRoleUser;
import com.example.model.vo.common.ResultCodeEnum;
import com.example.model.vo.system.SysMenuVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    public List<SysMenu> findNodes() {
        List<SysMenu> sysMenus = MenuHelper.buildTree(
                sysMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getIsDeleted, 0)));
        return sysMenus;
    }

    @Override
    public void deleteMenu(Long id) {
        //如果菜单有下级提示不能删除
        if (sysMenuMapper.selectCount(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getParentId, id)) > 0) {
            throw new GuiguException(ResultCodeEnum.NODE_ERROR);
        }
        sysMenuMapper.deleteById(id);

    }

    @Override
    public List<SysMenuVo> findUserMenuList(HttpServletRequest request) {
        String jwtToken = AuthContextUtil.getJwtToken();
        Long userId = JwtHelper.getUserId(jwtToken);
        if (userId == null) {
            throw new GuiguException(ResultCodeEnum.LOGIN_AUTH);
        }
        //根据用户id查出所有的菜单id
        List<Long> roleIdList = sysUserRoleMapper.selectList(
                        new LambdaQueryWrapper<SysRoleUser>()
                                .eq(SysRoleUser::getUserId, userId))
                .stream()
                .map(SysRoleUser::getRoleId)
                .collect(Collectors.toList());
        //根据角色id查询出所有的菜单id
        List<Long> menuIdList = new ArrayList<>();
        if (roleIdList != null && roleIdList.size() > 0) {
            menuIdList = sysRoleMenuMapper.selectList(
                            new LambdaQueryWrapper<SysRoleMenu>()
                                    .in(SysRoleMenu::getRoleId, roleIdList))
                    .stream()
                    .map(SysRoleMenu::getMenuId)
                    .collect(Collectors.toList());
        }
        List<SysMenu> sysMenus = new ArrayList<>();
        if (menuIdList !=null && menuIdList.size() > 0){
           sysMenus = sysMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>()
                    .in(SysMenu::getId, menuIdList));
        }
        List<SysMenu> sysMenus1 = MenuHelper.buildTree(sysMenus);

        List<SysMenuVo> sysMenuVos = buildMenus(sysMenus1);

        return sysMenuVos;
    }

    // 将List<SysMenu>对象转换成List<SysMenuVo>对象
    private List<SysMenuVo> buildMenus(List<SysMenu> menus) {

        List<SysMenuVo> sysMenuVoList = new LinkedList<SysMenuVo>();
        for (SysMenu sysMenu : menus) {
            SysMenuVo sysMenuVo = new SysMenuVo();
            sysMenuVo.setTitle(sysMenu.getTitle());
            sysMenuVo.setName(sysMenu.getComponent());
            List<SysMenu> children = sysMenu.getChildren();
            if (!CollectionUtils.isEmpty(children)) {
                sysMenuVo.setChildren(buildMenus(children));
            }
            sysMenuVoList.add(sysMenuVo);
        }
        return sysMenuVoList;
    }

}
